package com.zenithmind.version.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zenithmind.version.pojo.domain.FileVersion;
import com.zenithmind.version.pojo.vo.FileVersionVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

/**
 * 文件版本Mapper接口
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Mapper
public interface FileVersionMapper extends BaseMapper<FileVersion> {

    /**
     * 分页查询文件版本（包含关联信息）
     * 
     * @param page 分页参数
     * @param repositoryId 仓库ID
     * @param filePath 文件路径
     * @param branchName 分支名称
     * @return 分页结果
     */
    IPage<FileVersionVO> selectFileVersionPageWithDetails(Page<FileVersionVO> page,
                                                         @Param("repositoryId") String repositoryId,
                                                         @Param("filePath") String filePath,
                                                         @Param("branchName") String branchName);

    /**
     * 获取文件版本历史
     * 
     * @param repositoryId 仓库ID
     * @param filePath 文件路径
     * @param branchName 分支名称
     * @param limit 限制数量
     * @return 版本历史
     */
    @Select("SELECT fv.*, c.message as commit_message, c.author_name, c.commit_time " +
            "FROM file_version fv " +
            "LEFT JOIN commit c ON fv.commit_id = c.id " +
            "WHERE fv.repository_id = #{repositoryId} " +
            "AND fv.file_path = #{filePath} " +
            "AND (#{branchName} IS NULL OR fv.branch_name = #{branchName}) " +
            "AND fv.deleted = 0 " +
            "ORDER BY fv.version_number DESC " +
            "LIMIT #{limit}")
    List<FileVersionVO> selectFileVersionHistory(@Param("repositoryId") String repositoryId,
                                                @Param("filePath") String filePath,
                                                @Param("branchName") String branchName,
                                                @Param("limit") Integer limit);

    /**
     * 获取文件当前版本
     * 
     * @param repositoryId 仓库ID
     * @param filePath 文件路径
     * @param branchName 分支名称
     * @return 当前版本
     */
    @Select("SELECT fv.*, c.message as commit_message, c.author_name, c.commit_time " +
            "FROM file_version fv " +
            "LEFT JOIN commit c ON fv.commit_id = c.id " +
            "WHERE fv.repository_id = #{repositoryId} " +
            "AND fv.file_path = #{filePath} " +
            "AND fv.branch_name = #{branchName} " +
            "AND fv.deleted = 0 " +
            "ORDER BY fv.version_number DESC " +
            "LIMIT 1")
    FileVersionVO selectCurrentFileVersion(@Param("repositoryId") String repositoryId,
                                          @Param("filePath") String filePath,
                                          @Param("branchName") String branchName);

    /**
     * 获取提交中的文件列表
     * 
     * @param commitId 提交ID
     * @return 文件列表
     */
    @Select("SELECT fv.*, c.message as commit_message, c.author_name, c.commit_time " +
            "FROM file_version fv " +
            "LEFT JOIN commit c ON fv.commit_id = c.id " +
            "WHERE fv.commit_id = #{commitId} " +
            "AND fv.deleted = 0 " +
            "ORDER BY fv.file_path")
    List<FileVersionVO> selectCommitFiles(@Param("commitId") String commitId);

    /**
     * 获取分支中的文件列表
     * 
     * @param repositoryId 仓库ID
     * @param branchName 分支名称
     * @param directory 目录路径
     * @return 文件列表
     */
    List<FileVersionVO> selectBranchFiles(@Param("repositoryId") String repositoryId,
                                         @Param("branchName") String branchName,
                                         @Param("directory") String directory);

    /**
     * 比较两个版本的文件差异
     * 
     * @param repositoryId 仓库ID
     * @param filePath 文件路径
     * @param fromVersion 源版本
     * @param toVersion 目标版本
     * @return 差异信息
     */
    Object compareFileVersions(@Param("repositoryId") String repositoryId,
                              @Param("filePath") String filePath,
                              @Param("fromVersion") String fromVersion,
                              @Param("toVersion") String toVersion);

    /**
     * 获取文件版本内容
     * 
     * @param versionId 版本ID
     * @return 文件内容
     */
    @Select("SELECT content FROM file_version WHERE id = #{versionId} AND deleted = 0")
    String selectFileContent(@Param("versionId") String versionId);

    /**
     * 搜索文件
     * 
     * @param repositoryId 仓库ID
     * @param keyword 关键词
     * @param branchName 分支名称
     * @param fileType 文件类型
     * @param limit 限制数量
     * @return 文件列表
     */
    @Select("SELECT DISTINCT fv.*, c.message as commit_message, c.author_name, c.commit_time " +
            "FROM file_version fv " +
            "LEFT JOIN commit c ON fv.commit_id = c.id " +
            "WHERE fv.repository_id = #{repositoryId} " +
            "AND (#{branchName} IS NULL OR fv.branch_name = #{branchName}) " +
            "AND fv.deleted = 0 " +
            "AND (fv.file_path LIKE CONCAT('%', #{keyword}, '%') " +
            "OR fv.file_name LIKE CONCAT('%', #{keyword}, '%')) " +
            "AND (#{fileType} IS NULL OR fv.file_type = #{fileType}) " +
            "ORDER BY fv.update_time DESC " +
            "LIMIT #{limit}")
    List<FileVersionVO> searchFiles(@Param("repositoryId") String repositoryId,
                                   @Param("keyword") String keyword,
                                   @Param("branchName") String branchName,
                                   @Param("fileType") String fileType,
                                   @Param("limit") Integer limit);

    /**
     * 获取文件统计信息
     * 
     * @param repositoryId 仓库ID
     * @param filePath 文件路径
     * @return 统计信息
     */
    Object selectFileStatistics(@Param("repositoryId") String repositoryId,
                               @Param("filePath") String filePath);

    /**
     * 获取最大版本号
     * 
     * @param repositoryId 仓库ID
     * @param filePath 文件路径
     * @param branchName 分支名称
     * @return 最大版本号
     */
    @Select("SELECT COALESCE(MAX(version_number), 0) FROM file_version " +
            "WHERE repository_id = #{repositoryId} " +
            "AND file_path = #{filePath} " +
            "AND branch_name = #{branchName} " +
            "AND deleted = 0")
    Integer getMaxVersionNumber(@Param("repositoryId") String repositoryId,
                               @Param("filePath") String filePath,
                               @Param("branchName") String branchName);

    /**
     * 批量删除文件版本
     * 
     * @param versionIds 版本ID列表
     * @return 影响行数
     */
    @Update("<script>" +
            "UPDATE file_version SET deleted = 1, update_time = NOW() " +
            "WHERE id IN " +
            "<foreach collection='versionIds' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    int batchDeleteFileVersions(@Param("versionIds") List<String> versionIds);

    /**
     * 恢复文件版本
     * 
     * @param repositoryId 仓库ID
     * @param filePath 文件路径
     * @param branchName 分支名称
     * @param targetVersion 目标版本
     * @param userId 用户ID
     * @return 新版本ID
     */
    String restoreFileVersion(@Param("repositoryId") String repositoryId,
                             @Param("filePath") String filePath,
                             @Param("branchName") String branchName,
                             @Param("targetVersion") String targetVersion,
                             @Param("userId") String userId);

    /**
     * 复制文件到分支
     * 
     * @param repositoryId 仓库ID
     * @param filePath 文件路径
     * @param sourceBranch 源分支
     * @param targetBranch 目标分支
     * @param userId 用户ID
     * @return 新版本ID
     */
    String copyFileToBranch(@Param("repositoryId") String repositoryId,
                           @Param("filePath") String filePath,
                           @Param("sourceBranch") String sourceBranch,
                           @Param("targetBranch") String targetBranch,
                           @Param("userId") String userId);

    /**
     * 获取文件变更统计
     * 
     * @param repositoryId 仓库ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 变更统计
     */
    Object selectFileChangeStatistics(@Param("repositoryId") String repositoryId,
                                     @Param("startTime") String startTime,
                                     @Param("endTime") String endTime);

    /**
     * 获取热门文件
     * 
     * @param repositoryId 仓库ID
     * @param limit 限制数量
     * @return 热门文件
     */
    @Select("SELECT fv.file_path, fv.file_name, COUNT(*) as change_count, " +
            "MAX(fv.update_time) as last_change_time " +
            "FROM file_version fv " +
            "WHERE fv.repository_id = #{repositoryId} " +
            "AND fv.deleted = 0 " +
            "GROUP BY fv.file_path, fv.file_name " +
            "ORDER BY change_count DESC, last_change_time DESC " +
            "LIMIT #{limit}")
    List<Object> selectHotFiles(@Param("repositoryId") String repositoryId,
                               @Param("limit") Integer limit);
}
